#include <iostream>
#include <string>
#include <functional>
#include <unordered_map>
#include "../third_part/muduo/include/muduo/net/TcpServer.h"
#include "../third_part/muduo/include/muduo/net/EventLoop.h"
#include "../third_part/muduo/include/muduo/net/TcpConnection.h"
using namespace std;


class TranslateServer { // 翻译服务器类
public :
    TranslateServer(int port) 
        //      基本事件循环              服务器地址信息                  服务器名字                 是否立即复用端口
        :_server(&_baseloop, muduo::net::InetAddress("0.0.0.0", port), "TranslateServer", muduo::net::TcpServer::kNoReusePort)
    {
        // 将回调函数设置进_server
        auto connection_callback = std::bind(&TranslateServer::OnConnection, this, placeholders::_1);
        _server.setConnectionCallback(connection_callback);
        auto message_callback = std::bind(&TranslateServer::OnMessage, this, placeholders::_1, placeholders::_2, placeholders::_3);
        _server.setMessageCallback(message_callback);
        _dict = {
            {"hello", "你好"},
            {"left", "左边"},
            {"right", "右边"},
            {"answer", "答案"},
            {"apple", "苹果"}
        };

    }

    void Start() {
        // 1、开始事件监听
        _server.start(); 
        // 2、开始事件监控
        _baseloop.loop(); // 这是一个阻塞的死循环接口

    }

private :
    // 新链接建立成功时的回调函数
    // Onconnection接口应该是在连接建立成功或者关闭连接的时候调用
    void OnConnection(const muduo::net::TcpConnectionPtr& conn) {
        if (conn->connected()) { // 检查是否有连接建立成功
            cout << "新连接建立成功!" << endl;
        } else {
            cout << "新连接关闭!" << endl;
        }

    }
    // 通信连接收到请求时的回调函数
    string translate(string& str) {
        auto it = _dict.find(str);
        if (it == _dict.end()) {
            return "不知道!";
        }
        return it->second;
    }
    void OnMessage(const muduo::net::TcpConnectionPtr& conn, muduo::net::Buffer* buffer, muduo::Timestamp) {
        // 1、从buffer中把请求的数据取出来
        string req = buffer->retrieveAllAsString();
        // 2、调用translate进行翻译
        string resp = translate(req);
        // 3、向客户端进行响应结果
        conn->send(resp);

    }

private :
    // 因为_baseloop是需要传递到_server里面的，所以需要先定义
    muduo::net::EventLoop _baseloop; // 基本事件监控循环对象，是epoll的时间监控，会进行描述符的事件监控，触发io操作，触发io操作后，调用OnMessage进行业务处理
    muduo::net::TcpServer _server; // 服务器对象，主要用于设置回调函数，用于告诉服务器收到什么请求应该如何处理
    unordered_map<string, string> _dict;

};

int main(int argc, char* args[]) {
    if (argc != 2) {
        cout << "Usage:\n\r" << args[0] << " local_port\n" << endl;
        return 0; 
    }
    uint16_t port = stoi(args[1]);
    TranslateServer server(port);
    server.Start();

    return 0;
}